import puppeteer from "puppeteer";
import {
  waitForTimeout,
  getSiblingsElByTagName,
  reportLog,
  base64Encode,
} from "../utils/index.js";
import {
  validateEmail,
  getPmiRegisterCode,
} from "../api/modules/register/index.js";

const getCode = (email) => {
  return new Promise(async (resolve, reject) => {
    let GET_CODE_MAX_COUNT = 8; // 最多获取8次
    let getCodeCount = 0;
    let getPmiRegisterCodeTimer = setInterval(async () => {
      if (getCodeCount > GET_CODE_MAX_COUNT) {
        clearInterval(getPmiRegisterCodeTimer);
        reportLog("注册失败", {
          message: "注册失败，未收到验证码",
          username: userInfo.username,
          index: userInfo.index,
        });
        reject("注册失败");
      }
      let pmiRegisterCodeRes = await getPmiRegisterCode({
        email: base64Encode(email),
      });
      if (pmiRegisterCodeRes && pmiRegisterCodeRes.status == 0) {
        // 获取到验证码，清除定时器
        clearInterval(getPmiRegisterCodeTimer);

        let securityCode = pmiRegisterCodeRes.data.code;
        resolve(securityCode);
      }
      getCodeCount++;
    }, 30000);
  });
};

// 测试 注册 流程
export const register = async (userInfo) => {
  console.time(`${userInfo.index}-${userInfo.username}`)
  // 先验证一下邮箱是否可用
  await waitForTimeout(3000);
  let validateEmailData = new FormData();
  validateEmailData.append("Email", userInfo.email);
  const result = await validateEmail(validateEmailData);
  if (result !== true) {
    // 邮箱不可用
    reportLog("注册失败", {
      message: "注册失败，验证邮箱失败",
      error: result,
      username: userInfo.username,
      index: userInfo.index,
    });
    return
  }

  const browser = await puppeteer.launch({ headless: 'new' });
  const page = await browser.newPage();

  // 监听页面导航事件
  page.on("navigation", async (navigationEvent) => {
    console.log("页面跳转到：", navigationEvent.url);
  });

  // 设置导航超时时间为60秒
  await page.setDefaultNavigationTimeout(60000);

  // 在页面中注册方法
  page.exposeFunction("getSiblingsElByTagName", getSiblingsElByTagName);

  await page.setExtraHTTPHeaders({
    "Upgrade-Insecure-Requests": "1",
    "Sec-Fetch-User": "?1",
    "Sec-Ch-Ua": `"Not A(Brand";v="99", "Google Chrome";v="121", "Chromium";v="121"`,
    "Sec-Ch-Ua-Mobile": "?0",
    "Sec-Ch-Ua-Platform": "Windows",
    "Sec-Fetch-Dest": "document",
    "Sec-Fetch-Mode": "navigate",
    "Sec-Fetch-Site": "none",
    "User-Agent":
      "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36",
  });

  // 访问表单页面
  await page.setViewport({ width: 1920, height: 1024 });

  await page.goto("https://www.pmi.org/account-registration?returnUrl=%23RETURNURL%23");

  console.log(userInfo.index, '开始注册了')

  await page.type('input[name="FirstName"]', userInfo.firstName); // 姓

  await waitForTimeout(1000)

  await page.type('input[name="LastName"]', userInfo.lastName); // 名
  
  await waitForTimeout(1000)

  await page.type('input[name="Email"]', userInfo.email); // 邮箱

  await waitForTimeout(1000)

  await page.select('select[name="Country"]', userInfo.country); // 国家

  await waitForTimeout(1000)

  await page.type('input[name="CompanyName"]', userInfo.companyName); // 公司名

  await waitForTimeout(1000)

  // 使用page.evaluate获取select元素并进行操作
  await page.evaluate((userInfo) => {
    document.getElementById("8").value = userInfo["8"]; // Which of the following best matches or describes your current job title?
    document.getElementById("2").value = userInfo["2"]; // What year were you born? (YYYY)
    document.getElementById("1").value = userInfo["1"]; // How many total years of full-time work experience do you currently have?
    document.getElementById("4").value = userInfo["4"]; // How many years of experience do you have managing projects that last over 4 weeks?
    document.getElementById("3").value = userInfo["3"]; // Which best describes how you view project management as it relates to your career?
    document.getElementById("5").value = userInfo["5"]; // Does your organization have a project/program management office (PMO), or a group devoted to project management?
  }, userInfo);
  await page.select("#OrganizationFocus", userInfo.organizationFocus); // Primary Organization Focus (optional)

  await waitForTimeout(1000)

  await page.select("#AreaOfFocus", userInfo.areaOfFocus); // Area of Focus (optional)

  await waitForTimeout(1000)

  await page.type('input[name="Password"]', userInfo.password); // 密码

  await waitForTimeout(1000)

  await page.type('input[name="ConfirmPassword"]', userInfo.confirmPassword); // 重复密码

  await waitForTimeout(1000)

  await page.select(
    'select[name="SecurityQuestionId"]',
    userInfo.securityQuestionId
  ); // 安全验证问题

  await waitForTimeout(1000)

  await page.type('input[name="SecurityAnswer"]', userInfo.securityAnswer); // 安全验证答案

  await waitForTimeout(1000)

  await page.click('input[name="PrivacyAccepted"]'); // 勾选 Privacy Policy

  await waitForTimeout(1000)

  await page.click(".registerButton"); // 点击创建账户

  await page.waitForSelector("#SecurityCode"); // 等待验证码弹窗

  // 获取页面的HTML内容;
  const errorList = await page.evaluate(() => {
    let errorList = [];
    let errorText = "";
    let errorElList = document.querySelectorAll(".field-validation-error");
    errorElList.forEach((errorEl) => {
      if (errorEl.style.display !== "none") {
        let question = getSiblingsElByTagName(errorEl, "label")
          ? getSiblingsElByTagName(errorEl, "label").innerText
          : "";
        let description = errorEl.innerText;
        errorList.push({
          question,
          description,
        });
        errorText += `${question};${description};`;
      }
    });
    return errorList;
  });

  if (errorList.length > 0) {
    // 有错误
    reportLog("注册失败", {
      message: "注册失败，填写内容有误",
      error: errorList,
      username: userInfo.username,
      index: userInfo.index,
    });
  } else {
    try {
      // 获取验证码
      const securityCode = await getCode(userInfo.email);
      await page.type('input[name="SecurityCode"]', securityCode);
      await waitForTimeout(3000);
      await page.click(".btn-2fa-submit");
      await waitForTimeout(5000);

      reportLog("注册成功", {
        message: "注册成功",
        username: userInfo.username,
        pmi_account: userInfo.email,
        pmi_password: userInfo.password,
        index: userInfo.index,
      });
      console.timeEnd(`${userInfo.index}-${userInfo.username}`)
    } catch (error) {
      console.log(error);
    }
  }

  await browser.close();
};
